; *** Ultima
; *** Copyright 1998-2002 Zillions Development
; v.2.0

; You need to purchase Zillions of Games to load this rules file
; Visit the Zillions web site at http://www.zillions-of-games.com
(translate 
 ("White""白方") ("Black""黑方")
 ("Pawn" "夹") ("Long-Leaper" "跳")
 ("Chameleon" "仿") ("Coordinator" "矩")
 ("Immobilizer" "冻") ("Withdrawer" "拖") ("King" "王")
)
(version "2.0")

; Uses original style of Ultima: doesn't move # of squares based on rank

(define suicide
	capture
	add
)
(define squeeze
    (if (enemy? $1) ; Is there an enemy this direction?
       $1
	   (if (friend? $1) capture)
	   (opposite $1)
	)
)
(define chameleon-squeeze
	(if (piece? Pawn $1) (squeeze $1))
)
(define chameleon-coordinate
	(while (on-board? $1)
		$1
		(if (and enemy? (piece? Coordinator) (position-flag? king-line)) capture)
	)
	(go to)
)
(define chameleon-add
	(if (flag? orthogonal?)
		(chameleon-squeeze $1)
		(chameleon-squeeze $2)
		(chameleon-squeeze $3)	
	)
	(if (flag? WD-capture?)
		(go from) (opposite $1) capture (go to)
	)
	(if (not-position-flag? king-line)
		(chameleon-coordinate n)
		(chameleon-coordinate e)
		(chameleon-coordinate s)
		(chameleon-coordinate w)
	)
	add
)
(define chameleon-slide
	(set-flag WD-capture? (and (enemy? (opposite $1)) (piece? Withdrawer (opposite $1))))
	(if (and (enemy? $1) (piece? King $1))
		$1 to (chameleon-add $1 $2 $3)
	 else
		(while (empty? $1)
			$1 to (chameleon-add $1 $2 $3)
		)
		(if (and (enemy? $1) (piece? Long-Leaper $1))
			$1
			mark
			(while (empty? $1)
				$1 to
				back capture
				(go to)
				(chameleon-add $1 $2 $3)
			)
			(if (and (enemy? $1) (piece? Long-Leaper $1))
				$1
				(while (empty? $1)
					$1 to
					(opposite $1) (while empty? (opposite $1)) capture
					back capture
					(go to)
					(chameleon-add $1 $2 $3)
				)
			)
		)
	)
)

(define coordinate
	(while (on-board? $1)
		$1
		(if (and enemy? (position-flag? king-line)) capture)
	)
	(go to)
)
(define coordinator-slide
	(while (empty? $1)
		$1
		to
		(if (not-position-flag? king-line)
			(coordinate n) (coordinate e) (coordinate s) (coordinate w)
		)
		add
	)
)

(define make-king-line
	(while (on-board? $1) $1 (set-position-flag king-line true))
)
(define make-king-lines
  ;  Mark king
	a1
	(while (or (not-piece? King) not-friend?) next)
	mark
  ;  Make lines
	(make-king-line n) back
	(make-king-line e) back
	(make-king-line s) back
	(make-king-line w) (go from)
)
(define king-shift
	(if (and (on-board? $1) (not-friend? $1)) $1 add (go from))
)
(define immobilizer-slide
	(while (empty? $1) $1 add)
)
(define long-leaper-slide
	(while (empty? $1) $1 to add)
	(if (enemy? $1)
		$1
		(if (empty? $1)
			mark
			capture
			$1 to add
			(while (empty? $1) $1 to back capture (go to) add)
			(if (enemy? $1)
				$1
				(if (empty? $1)
					capture
					$1 to
					back capture (go to) add
					(while (empty? $1)
						$1 to
						(while (empty? (opposite $1)) (opposite $1))
						(opposite $1)
						capture
						back capture
						(go to) add
					)
					(if (enemy? $1)
						$1
						(while (empty? $1)
							$1 to
							(opposite $1) (if empty? (opposite $1)) capture
							(opposite $1) (opposite $1) (if empty? (opposite $1)) capture
							(opposite $1) (opposite $1) (if empty? (opposite $1)) capture
							(go to) add
						)
					)
				)
			)
		)
	)
) 

(define withdrawer-slide
	(if (enemy? (opposite $1))
		(while (empty? $1)
			(mark $1)
			(go from) (opposite $1) capture
			back add
		)
	 else
		(while (empty? $1)
			$1 add
		)
	)
)

(define pawn-slide
	(while (empty? $1)
		$1
		(squeeze $1)
		(squeeze $2)
		(squeeze $3)
		add
	)
)

; Is there an immobilizer adjacent?
(define is-imobilizer? (and (enemy? $1) (piece? Immobilizer $1)) )
(define immobilized?
   (or (is-imobilizer? n) (is-imobilizer? ne) (is-imobilizer? e)
       (is-imobilizer? se) (is-imobilizer? s) (is-imobilizer? sw)
       (is-imobilizer? w) (is-imobilizer? nw)
   )
)
; Is there an immobilizer or chameleon adjacent?
(define is-imobilizer2? (and (enemy? $1) (or (piece? Immobilizer $1) (piece? Chameleon $1))) )
(define immobilized2?
   (or (is-imobilizer2? n) (is-imobilizer2? ne) (is-imobilizer2? e)
       (is-imobilizer2? se) (is-imobilizer2? s) (is-imobilizer2? sw)
       (is-imobilizer2? w) (is-imobilizer2? nw)
   )
)

(define Board-Definitions
  (image "images\Chess\SHaag\Chess8x8.bmp" "images\Chess\Chess8x8.bmp")
  (grid
     (start-rectangle 5 5 53 53)
     (dimensions
         ("a/b/c/d/e/f/g/h" (49 0)) ; files
         ("8/7/6/5/4/3/2/1" (0 49)) ; ranks
     )
     (directions (n 0 -1) (e 1 0) (s 0 1) (w -1 0) 
			     (ne 1 -1) (nw -1 -1) (se 1 1) (sw -1 1)
				 (next 1 0)
     )
  )
  (links next (h1 a2) (h2 a3) (h3 a4) (h4 a5) (h5 a6) (h6 a7) (h7 a8))
  (symmetry Black (n s)(s n) (nw sw)(sw nw) (ne se)(se ne))
)


; **************************** ULTIMA ****************************
(game
   (title "Ultima")
   (description "这是一款全新的高能棋类。除王以外几乎所有子都很特殊。吃掉对方王，或使对方无子可动获胜。右键点击棋子查看详细信息。")
   (strategy "Try to avoid getting your King immobilized as this is
      a very dangerous situation.  To avoid captures by an enemy
	  Coordinator, be watchful of all your pieces that are on the
	  same rank or file as the enemy King.")
   (history "Ultima was invented by Robert Abbott and first appeared,
      without a name, in the December 1962 issue of `Recreational
      Mathematics Magazine` (forerunner of the `Journal of Recreational
      Mathematics`).  The game was later published, as Ultima, in
      `Abbott's New Card Games.`  Abbott revised the rules for the paperback
      edition of the book, adding a rule limiting movement depending on
      what rank a piece begins on, but that rule was not widely accepted,
      and this implementation uses Abbott's original rules.")
   (option "prevent flipping" 2)
   (click-sound "Audio\\Pickup.wav")
   (release-sound "Audio\\WoodThunk.wav")
   (players White Black)
   (turn-order White Black)
   (board (Board-Definitions))

   (board-setup
      (White
         (Pawn a2 b2 c2 d2 e2 f2 g2 h2)
         (Long-Leaper b1 g1)
         (Chameleon c1 f1)
         (Coordinator h1)
		 (Immobilizer a1)
         (Withdrawer e1)
         (King d1)
      )
      (Black
         (Pawn a7 b7 c7 d7 e7 f7 g7 h7)
         (Long-Leaper b8 g8)
         (Chameleon c8 f8)
         (Coordinator a8)
		 (Immobilizer h8)
         (Withdrawer d8)
         (King e8)
      )
   )

   (piece
      (name Pawn)
 	  (help "夹击者：横直不限，夹吃")
	  (description "夹击者\走法横直不限，吃法类似围棋的“夹”棋形。\即：夹击者走棋之后，若刚好把一个对方子横向或纵向夹在夹击者和其他棋子中间，那么对方子被吃。
\如下：○●夹，○为友军，则敌子●被吃。")
      (image White "images\Chess\SHaag\wpawn.bmp" "images\Chess\wpawn.bmp"
             Black "images\Chess\SHaag\bpawn.bmp" "images\Chess\bpawn.bmp")
      (moves (
		(if (immobilized?)
			(suicide)
		 else
			(verify (not (immobilized?)))
			(pawn-slide n e w) (go from)
			(pawn-slide e s n) (go from)
			(pawn-slide s w e) (go from)
			(pawn-slide w n s)
		)
      ))
   )

   (piece
      (name Long-Leaper)
 	  (help "跳吃者：八方不限，吃子必须跳杀")
	  (description "跳吃者\\八方移动不限格数。
\跳吃者拥有独特的“跳杀”技能，即跳吃者吃子须越过一个目标子到它后面的一个空格，然后将跳过的棋子捕杀。可以同方向连跳。")
      (image White "images\Chess\SHaag\wknight.bmp" "images\Chess\wknight.bmp"
             Black "images\Chess\SHaag\bknight.bmp" "images\Chess\bknight.bmp")
      (moves (
		(if (immobilized?)
			(suicide)
		 else
			(long-leaper-slide n) (go from)
			(long-leaper-slide e) (go from)
			(long-leaper-slide s) (go from)
			(long-leaper-slide w) (go from)
			(long-leaper-slide ne) (go from)
			(long-leaper-slide nw) (go from)
			(long-leaper-slide se) (go from)
			(long-leaper-slide sw)
		)
      ))
   )

   (piece
      (name Chameleon)
 	  (description "模仿者\八方移动不限。\模仿者拥有“模仿”技能，吃子方式和被吃子相同。即：\
模仿者吃跳吃者：跳过对方落到它后面一格。仅可连吃跳吃者。\
模仿者吃夹击者：夹击攻击不变，但必须横直移动到夹击者旁边。\
模仿者吃拖杀者：向拖杀者的方向反方向移动吃掉。\
模仿者吃指示者：王与对方指示者同一直线时，移动到指示者与王连线垂直的方向即可。\
模仿者对冻结者：只要模仿者在冻结者周围，双方均不能移动。注意点击被冻结的棋子会自杀！\
模仿者吃王：只能八方一格吃王。\
模仿者无法吃模仿者。")
     (image White "images\Chess\SHaag\wbishop.bmp" "images\Chess\wbishop.bmp"
            Black "images\Chess\SHaag\bbishop.bmp" "images\Chess\bbishop.bmp")
	  (help "模仿者：八方不限，吃什么子用什么子的吃法")
      (moves (
		(if (immobilized?)
			(suicide)
		 else
			(verify (not (immobilized?)))
			(make-king-lines)
			(set-flag orthogonal? true)
			(chameleon-slide n e w) (go from)
			(chameleon-slide s e w) (go from)
			(chameleon-slide e n s) (go from)
			(chameleon-slide w n s) (go from)
			(set-flag orthogonal? false)
			(chameleon-slide ne n n) (go from)
			(chameleon-slide nw n n) (go from)
			(chameleon-slide se n n) (go from)
			(chameleon-slide sw n n)
 		)
      ))
   )

   (piece
      (name Immobilizer)
	  (help "冻结者：八方移动不限，冻结周围8格敌人")
	  (description "冻结者：八方移动不限。\冻结者技能是“冰冻”，其周围8格的敌方棋子无法行动，直到冻结者被吃或离开作用范围。\点击被冰冻的棋子(王除外)可以让其自杀。")
      (image White "images\Chess\SHaag\WDownRook.bmp" "images\Chess\WDownRook.bmp"
             Black "images\Chess\SHaag\BDownRook.bmp" "images\Chess\BDownRook.bmp")
      (moves (
		(if (immobilized2?)
			(suicide)
		 else
			(verify (not (immobilized2?)))
			(immobilizer-slide n) (go from)
			(immobilizer-slide e) (go from)
			(immobilizer-slide s) (go from)
			(immobilizer-slide w) (go from)
			(immobilizer-slide ne) (go from)
			(immobilizer-slide nw) (go from)
			(immobilizer-slide se) (go from)
			(immobilizer-slide sw)
		)
      ))
  )

   (piece
      (name Coordinator)
 	  (help "指示者：八方不限，移动结束后杀死与己方王构成的矩形的另外两个对角的敌子")
 	  (description "指示者：八方不限。\指示者技能是“指示”。它走棋完毕后，会杀死[与它同列且与己方王同行]的敌子，和[与它同行且与己方王同列]的敌子。\
简单来说，分别以它和己方王为中心，按棋盘行/列画两条线，构成一个矩形，另外两个对角若有敌子，则击杀。\显然，指示者若与王同横/直线，无法吃子。")
     (image White "images\Chess\SHaag\wrook.bmp" "images\Chess\wrook.bmp"
            Black "images\Chess\SHaag\brook.bmp" "images\Chess\brook.bmp")
      (moves (
		(if (immobilized?)
			(suicide)
		 else
			(make-king-lines)
			(coordinator-slide n) (go from)
			(coordinator-slide e) (go from)
			(coordinator-slide s) (go from)
			(coordinator-slide w) (go from)
			(coordinator-slide ne) (go from)
			(coordinator-slide nw) (go from)
			(coordinator-slide se) (go from)
			(coordinator-slide sw)
		)
      ))
 )

  (piece
      (name Withdrawer)
	  (description "拖杀者：八方向不限。\拖杀者技能“拖”，只能吃相邻棋子。且必须沿对方的反方向移动——如果想吃右边就必须向左，想吃左边必须向右。")
	  (help "拖杀者：八方不限，吃子需反方向移动")
      (image White "images\Chess\SHaag\wqueen.bmp" "images\Chess\wqueen.bmp"
             Black "images\Chess\SHaag\bqueen.bmp" "images\Chess\bqueen.bmp")
      (moves (
		(if (immobilized?)
			(suicide)
		 else
			(verify (not (immobilized?)))
			(withdrawer-slide n) (go from)
			(withdrawer-slide e) (go from)
			(withdrawer-slide s) (go from)
			(withdrawer-slide w) (go from)
			(withdrawer-slide ne) (go from)
			(withdrawer-slide nw) (go from)
			(withdrawer-slide se) (go from)
			(withdrawer-slide sw)
		)
      ))
   )

   (piece
      (name King)
      (description "王：同国象王。无法在被冰冻的场合自杀，也不可送吃。")
	  (help "王：八方1格。被吃输")
      (image White "images\Chess\SHaag\wking.bmp" "images\Chess\wking.bmp"
             Black "images\Chess\SHaag\bking.bmp" "images\Chess\bking.bmp")
      (moves (
		(verify (not (immobilized?)))
		(king-shift n)
		(king-shift e)
		(king-shift s)
		(king-shift w)
		(king-shift ne)
		(king-shift nw)
		(king-shift se)
		(king-shift sw)
      ))
    )

   (loss-condition (White Black) (captured King) )
   (loss-condition (White Black) stalemated )
)


